package com.samuel.basics.controller.admin;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.samuel.basics.annotation.CacheLock;
import com.samuel.basics.annotation.OperateLog;
import com.samuel.basics.base.BaseController;
import com.samuel.basics.constant.CommonConstant;
import com.samuel.basics.constant.OperateConstant;
import com.samuel.basics.entity.RoleEntity;
import com.samuel.basics.entity.UserEntity;
import com.samuel.basics.enums.ResultEnum;
import com.samuel.basics.exception.CustomException;
import com.samuel.basics.service.RoleService;
import com.samuel.basics.service.UserService;
import com.samuel.basics.utils.Md5Util;
import com.samuel.basics.utils.RandomUtil;
import com.samuel.basics.utils.RegexUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 用户管理-前端控制器
 * </p>
 *
 * @author kaiji
 * @since 2019-08-17
 */
@Controller
@RequestMapping("/user")
public class UserController extends BaseController {
    
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;

    private final static String PREFIX = "user/";

    @GetMapping("/list")
    public Object list() {
        return PREFIX + LIST;
    }

    @ResponseBody
    @GetMapping("/listJson")
    @OperateLog(operateModule = "用户管理", operateType = OperateConstant.SELECT, operateDesc = "查看用户列表")
    public Object listJson(Page<UserEntity> iPage, UserEntity userEntity) {
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(userEntity.getUsername())) {
            queryWrapper.lambda().like(UserEntity::getUsername, userEntity.getUsername().trim());
        }
        iPage = userService.page(iPage, queryWrapper);
        return page2LayUiTablePage(iPage);
    }

    @GetMapping("/view")
    @CacheLock(prefix = "view")
    @OperateLog(operateModule = "用户管理", operateType = OperateConstant.VIEW, operateDesc = "查看用户详情")
    public String view(String id, ModelMap modelMap) {
        if (StringUtils.isBlank(id)) {
            throw new CustomException(ResultEnum.GET_ERROR, "id找不到");
        }
        UserEntity userModel = userService.getById(id);
        modelMap.put("userModel", userModel);
        // modelMap.put("imageView", webConfig.getViewPath());
        return PREFIX + VIEW;
    }

    @GetMapping("update")
    @OperateLog(operateModule = "用户管理", operateType = OperateConstant.VIEW, operateDesc = "跳转更新页面")
    public String toUpdate(String id, ModelMap modelMap) {
        if (StringUtils.isBlank(id)) {
            throw new CustomException(ResultEnum.UPDATE_ERROR, "请选择一条数据！");
        }

        UserEntity userEntity = userService.getById(id);
        if (userEntity == null) {
            logger.info("查询不到数据！");
            throw new CustomException(ResultEnum.UPDATE_ERROR, "请选择一条数据！");
        }
        Set<String> codeList = userService.getRoleByPhone(userEntity.getPhone());
        // 查询全部的角色
        List<RoleEntity> roleList = roleService.list();
        modelMap.put("userEntity", userEntity);
        modelMap.put("roleList", roleList);
        modelMap.put("codeList", codeList);
        // modelMap.put("imageView", webConfig.getViewPath());
        return PREFIX + INPUT;
    }

    @ResponseBody
    @PostMapping("/update")
    @CacheLock(prefix = "user-update")
    @OperateLog(operateModule = "用户管理", operateType = OperateConstant.UPDATE, operateDesc = "修改用户信息")
    public JSONObject update(UserEntity userEntity) {
        JSONObject jsonObject = validate(userEntity, CommonConstant.DATA_UPDATE_TYPE);
        Integer code = jsonObject.getIntValue(CommonConstant.AjaxCode.CODE);
        if (code.equals(CommonConstant.AjaxCode.FAIL_CODE)) {
            return jsonObject;
        }

        jsonObject = new JSONObject();
        boolean flag = userService.updateByUserInfo(userEntity);

        if (flag) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "修改用户数据成功！");
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.SUCCESS_CODE);
        } else {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "修改用户数据失败！");
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
        }
        return jsonObject;
    }

    @GetMapping("save")
    @OperateLog(operateModule = "用户管理", operateType = OperateConstant.VIEW, operateDesc = "跳转保存用户页面")
    public String toSave(ModelMap modelMap) {
        // 查询全部的角色
        List<RoleEntity> roleList = roleService.list();
        modelMap.put("roleList", roleList);
        return PREFIX + INPUT;
    }

    @ResponseBody
    @PostMapping("save")
    @CacheLock(prefix = "save")
    @OperateLog(operateModule = "用户管理", operateType = OperateConstant.SAVE, operateDesc = "保存用户信息")
    public JSONObject save(UserEntity userEntity) {
        JSONObject jsonObject = validate(userEntity, CommonConstant.DATA_SAVE_TYPE);
        Integer code = jsonObject.getIntValue(CommonConstant.AjaxCode.CODE);
        if (code.equals(CommonConstant.AjaxCode.FAIL_CODE)) {
            return jsonObject;
        }

        jsonObject = new JSONObject();
        try {
            userEntity.setSalt(RandomUtil.randomString(8));
            userEntity.setCreateDate(LocalDateTime.now());
            userEntity.setPassword(Md5Util.getMd5(CommonConstant.PASSWORD));
            userService.saveAndRole(userEntity);
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.SUCCESS_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "保存数据成功！");
        } catch (Exception e) {
            logger.error("保存用户数据异常！原因：{}", e.getMessage());
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, e.getMessage());
        }
        return jsonObject;
    }

    /**
     * 批量删除
     *
     * @param ids id集合
     */
    @ResponseBody
    @PostMapping("delete")
    @CacheLock(prefix = "delete")
    @OperateLog(operateModule = "用户管理", operateType = OperateConstant.DELETE, operateDesc = "删除用户信息，可以批量删除")
    public JSONObject delete(String ids) {
        JSONObject jsonObject = new JSONObject();
        if (StringUtils.isEmpty(ids)) {
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请至少选择一条数据！");
            return jsonObject;
        }

        try {
            userService.removeByIds(Arrays.asList(ids.split(CommonConstant.DOC_FLAG)));
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.SUCCESS_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "删除用户数据成功！");
        } catch (Exception e) {
            logger.error("删除失败！原因： {}", e.getMessage());
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "删除用户数据失败！");
        }

        return jsonObject;
    }

    protected JSONObject validate(UserEntity userEntity, int type) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
        if (userEntity == null) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "对象不能为空！");
            return jsonObject;
        }

        if (StringUtils.isEmpty(userEntity.getPhone())) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请填写手机号！");
            return jsonObject;
        }

        // 判断手机号是否合法
        if (!RegexUtil.matchMobile(userEntity.getPhone())) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "手机号不合法！");
            return jsonObject;
        }

        if (StringUtils.isEmpty(userEntity.getUsername())) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请填写用户名称！");
            return jsonObject;
        }

        if (userEntity.getStatus() == null) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请选择用户状态！");
            return jsonObject;
        } else if (userEntity.getStatus() != 0 && userEntity.getStatus() != 1) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "非法的参数！");
            return jsonObject;
        }
        // 判断是否有角色
        List<String> roleIds = userEntity.getRoleIds();
        if (roleIds == null || roleIds.size() <= 0) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请选择角色！");
            return jsonObject;
        }

        if (type == CommonConstant.DATA_UPDATE_TYPE) {
            if (StringUtils.isEmpty(userEntity.getId())) {
                jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请至少选择一个对象数据！");
                return jsonObject;
            }
            // 判断用户是否存在
            UserEntity user = userService.getById(userEntity.getId());
            if (user == null) {
                jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "该数据被删除，已经不存在！");
                return jsonObject;
            }
            // 判断用户手机号是否存在
            user = userService.getUserByExist(userEntity.getId(), userEntity.getPhone());
            if (user != null) {
                jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "该手机号已存在！");
                return jsonObject;
            }

        } else if (type == CommonConstant.DATA_SAVE_TYPE) {
            // 判断用户手机号是否存在
            UserEntity user = userService.getUserByExist(null, userEntity.getPhone());
            if (user != null) {
                jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "该手机号已存在！");
                return jsonObject;
            }

        } else {
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "数据类型错误！");
            return jsonObject;
        }
        jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.SUCCESS_CODE);
        jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "数据验证成功！");
        return jsonObject;
    }
}
